package cc.z8g.browser

import android.app.Activity
import android.app.Application
import android.os.Build
import android.os.StrictMode
import android.webkit.WebView
import cc.z8g.browser.database.bookmark.BookmarkDAO
import cc.z8g.browser.database.bookmark.BookmarkParser
import cc.z8g.browser.log.Logger
import cc.z8g.browser.utils.FileUtils
import cc.z8g.browser.utils.MemoryLeakUtils
import cc.z8g.browser.utils.ThreadPool
import io.reactivex.rxjava3.core.Single
import kotlin.system.exitProcess

/**
 * The browser application.
 */
class BrowserApp : Application() {

    companion object {
        private const val TAG = "BrowserApp"


        private lateinit var app : Application

        @JvmStatic
        fun getApplication(): Application = app
    }

    override fun onCreate() {
        super.onCreate()
        app = this
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(
                StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build()
            )
            StrictMode.setVmPolicy(
                StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build()
            )
        }

        if (Build.VERSION.SDK_INT >= 28) {
            if (getProcessName() == "$packageName:incognito") {
                WebView.setDataDirectorySuffix("incognito")
            }
        }

        val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()

        Thread.setDefaultUncaughtExceptionHandler { thread, ex ->
            if (BuildConfig.DEBUG) {
                FileUtils.writeCrash(ex)
                exitProcess(2)
            }

            if (defaultHandler != null) {
                defaultHandler.uncaughtException(thread, ex)
            } else {
                FileUtils.writeCrash(ex)
            }
        }

        val bookmarkModel = BookmarkDAO.getImpl()
        Single.fromCallable(bookmarkModel::count)
            .filter { it == 0L }
            .flatMapCompletable {
                val assetsBookmarks = BookmarkParser.importBookmarksFromAssets(this@BrowserApp)
                bookmarkModel.addBookmarkList(assetsBookmarks)
            }
            .subscribeOn(ThreadPool.getDBScheduler())
            .subscribe()

        if (BuildConfig.DEBUG) {
            LeakCanaryUtils.setup() // 开启 leakCanary
            WebView.setWebContentsDebuggingEnabled(true) // 支持 chrome://inspect
        }

        registerActivityLifecycleCallbacks(object : MemoryLeakUtils.LifecycleAdapter() {
            override fun onActivityDestroyed(activity: Activity) {
                Logger.d(TAG, "Cleaning up after the Android framework")
                MemoryLeakUtils.clearNextServedView(activity, this@BrowserApp)
            }
        })
    }
}
